#include "syntax_parser.h"
#include "errors_warnings.h"

#include "main_container.h"
extern MainContainer * CompilerData;


// <data_type> ~ <name> <template_use>  {NAME}
// <data_type> ~ <name>  {NAME}
// <data_type> ~ int  {int}
// <data_type> ~ float  {float}
// <data_type> ~ bool  {bool}
// <data_type> ~ state  {state}
// <data_type> ~ time  {time}
// <data_type> ~ void  {void}
// <data_type> ~ Facility  {Facility}
// <data_type> ~ Storage  {Storage}
// <data_type> ~ Queue  {Queue}
// <data_type> ~ ADTable  {ADTable}
// <data_type> ~ Group  {Group}
// <data_type> ~ OutputStream  {OutputStream}

void Parser::Parse_DataType(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_DataType");
#endif
	LexicUnit currentUnit;
	
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);


	if(currentUnit.type == LUTypeIdentifier)
	{

		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Name(newNode0);
		
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThan)
		{
			parent->Production = Gr_DataType__Name_TemplateUse;
			// process nonterminal symbol <template_use> 
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			Parse_TemplateUse(newNode1);
		}
		else
		{
			parent->Production =Gr_DataType__Name;
		}
	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInt
	)
	{
		// write type of production in this node
		parent->Production = Gr_DataType__int;

		// process terminal symbol 'int' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFloat
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__float;

		// process terminal symbol 'float' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBool
	)
	{
		// write type of production in this node
		parent->Production = Gr_DataType__bool;

		// process terminal symbol 'bool' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordState
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__state;

		// process terminal symbol 'state' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTime
	)
	{
		// write type of production in this node
		parent->Production = Gr_DataType__time;

		// process terminal symbol 'time' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordVoid
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__void;

		// process terminal symbol 'void' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFacility
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__Facility;

		// process terminal symbol 'Facility' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStorage
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__Storage;

		// process terminal symbol 'Storage' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordQueue
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__Queue;

		// process terminal symbol 'Queue' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordADTable
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__ADTable;

		// process terminal symbol 'ADTable' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGroup
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__Group;

		// process terminal symbol 'Group' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutputStream
	)
	{
		// write type of production in this node
		parent->Production =Gr_DataType__OutputStream;

		// process terminal symbol 'OutputStream' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_DATA_TYPE_BEGINING);
		// This is recovoring from error
        this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_DataType");
#endif
}




// <enum_definition> ~ enum NAME { <enum_names> }  {enum}
void Parser::Parse_EnumDefinition(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_EnumDefinition");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEnum
	)
	{
		// write type of production in this node
		parent->Production = Gr_EnumDefinition__enum_NAME_spLCBrac_EnumNames_spRCBrac;

		// process terminal symbol 'enum' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process terminal symbol 'NAME' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( 
			currentUnit.type == LUTypeIdentifier
		)
		{
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_NAME_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process terminal symbol '{' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( 
			currentUnit.type == LUTypeSpecialCharacter &&
			currentUnit.subtype == SpecialCharacterLeftCurlyBrace
			)
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LEFT_CURLY_BRACE_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process nonterminal symbol <enum_names> 
		SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode3);
		Parse_EnumNames(newNode3);

		// process terminal symbol '}' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter &&
			currentUnit.subtype == SpecialCharacterRightCurlyBrace
			)
		{
			SyntaxTreeNode * newNode4 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode4);
			newNode4->LexUnitID=this->CurrentLexicPosition;
			newNode4->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_RIGHT_CURLY_BRACE_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ENUM_DEFINITION_BEGINING);
		// This is recovoring from error
        this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_EnumDefinition");
#endif
}



// <enum_names> ~ NAME <enum_names_add>  {NAME}
void Parser::Parse_EnumNames(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_EnumNames");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeIdentifier
	)
	{
		// write type of production in this node
		parent->Production = Gr_EnumNames__NAME_EnumNamesAdd;

		// process terminal symbol 'NAME' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <enum_names_add> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_EnumNamesAdd(newNode1);

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ENUM_NAMES_BEGINING);
		// This is recovoring from error
        this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_EnumNames");
#endif
}


// <enum_names_add> ~ <name_comma_add> <enum_names_add>  {,}
// <enum_names_add> ~ ? {}}
void Parser::Parse_EnumNamesAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_EnumNamesAdd");
#endif
	LexicUnit currentUnit;

	do{
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if(
		
			currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma
		)
		{
			// write type of production in this node
			parent->Production = Gr_EnumNamesAdd__NameCommaAdd_EnumNamesAdd;

			// process nonterminal symbol <name_comma_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_NameCommaAdd(newNode0);

		}

		else if(
		
			currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace
		)
		{
			// write type of production in this node
			parent->Production =Gr_EnumNamesAdd__NameCommaAdd_EnumNamesAdd;
			break;
		}


		else
		{
			// ERROR has been found
			// REPORT ERROR
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ENUM_NAMES_ADD_BEGINING);
			// This is recovoring from error
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_EnumNamesAdd");
#endif
}

// <template_definition> ~ template <template_use>  {template}
// <template_definition> ~ ? {class}
void Parser::Parse_TemplateDefinition(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_TemplateDefinition");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype ==  KeywordTemplate
	)
	{
		// write type of production in this node
		parent->Production = Gr_TemplateDefinition__template_TemplateUse;

		// process terminal symbol 'template' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <template_use> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_TemplateUse(newNode1);

	}

	else if(
	
		currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordClass
	)
	{
		// write type of production in this node
		parent->Production =Gr_TemplateDefinition__epsilon;

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_TEMPLATE_DEFINITION_BEGINING);
		// This is recovoring from error
        this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_TemplateDefinition");
#endif
}


// <template_use> ~ < <templates_list> >  {<}
void Parser::Parse_TemplateUse(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_TemplateUse");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThan
	)
	{
		// write type of production in this node
		parent->Production = Gr_TemplateUse__opLess_TemplatesList_opGreat;

		// process terminal symbol '<' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <templates_list> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_TemplatesList(newNode1);

		// process terminal symbol '>' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( 
			currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorGreaterThan )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID = this->CurrentLexicPosition;
			newNode2->Production = Gr_Terminal;
			
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_GREATER_THAN_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_TEMPLATE_USE_BEGINING);
		// This is recovoring from error
        this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_TemplateUse");
#endif
}




// <templates_list> ~ NAME <templates_list_add>  {NAME}
void Parser::Parse_TemplatesList(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_TemplatesList");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeIdentifier
	)
	{
		// write type of production in this node
		parent->Production = Gr_TemplatesList__NAME_TemplatesListAdd;

		// process terminal symbol 'NAME' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <templates_list_add> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_TemplatesListAdd(newNode1);

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_TEMPLATES_LIST_BEGINING);
		// This is recovoring from error
        this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_TemplatesList");
#endif
}


// <templates_list_add> ~ <name_comma_add> <templates_list_add>  {,}
// <templates_list_add> ~ ? {>}
void Parser::Parse_TemplatesListAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_TemplatesListAdd");
#endif
	LexicUnit currentUnit;
	do{
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if(
		
			currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma
		)
		{
			// write type of production in this node
			parent->Production = Gr_TemplatesListAdd__NameCommaAdd_TemplatesListAdd;

			// process nonterminal symbol <name_comma_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_NameCommaAdd(newNode0);

		}

		else if(
		
			currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorGreaterThan
		)
		{
			// write type of production in this node
			parent->Production = Gr_TemplatesListAdd__NameCommaAdd_TemplatesListAdd;
			break;

		}


		else
		{
			// ERROR has been found
			// REPORT ERROR
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_TEMPLATES_LIST_ADD_BEGINING);
			// This is recovoring from error
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_TemplatesListAdd");
#endif
}



// <class_inherit_name> ~ <name> <template_use>  {NAME}
// <class_inherit_name> ~ <name>  {NAME}
void Parser::Parse_ClassInheritName(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ClassInheritName");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);


	if(currentUnit.type == LUTypeIdentifier)
	
	{
		
		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Name(newNode1);

		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThan)
		{
			// write type of production in this node
			parent->Production = Gr_ClassInheritName__Name_TemplateUse;
		
			// process nonterminal symbol <template_use> 
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			Parse_TemplateUse(newNode2);

		}
		else
		{
			// write type of production in this node
			parent->Production = Gr_ClassInheritName__Name;
		}
	}
	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_INHERIT_NAME_BEGINING);
		// This is recovoring from error
        this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ClassInheritName");
#endif
}


// <name_comma_add> ~ , NAME  {,}
void Parser::Parse_NameCommaAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_NameCommaAdd");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma
	)
	{
		// write type of production in this node
		parent->Production = Gr_NameCommaAdd__spComma_NAME;

		// process terminal symbol ',' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process terminal symbol 'NAME' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( 
			currentUnit.type == LUTypeIdentifier
		)
		{
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_NAME_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_NAME_COMMA_ADD_BEGINING);
		// This is recovoring from error
        this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_NameCommaAdd");
#endif
}

/* TODO - was error here
void Parser::Parse_ClassBody(SyntaxTreeNode *parent)
{

}
*/